home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / Signature.java < prev    next >
Text File  |  1998-09-22  |  22KB  |  589 lines

  1. /*
  2.  * @(#)Signature.java    1.49 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15.  
  16. package java.security;
  17.  
  18. import java.util.*;
  19. import java.io.*;
  20. /**
  21.  * This Signature class is used to provide the functionality of a
  22.  * digital signature algorithm, such as <tt>RSA with MD5</tt> or
  23.  * <tt>DSA</tt>. Digital signatures are used for authentication and
  24.  * integrity assurance of digital data.
  25.  *
  26.  * </dl> 
  27.  *
  28.  * <p>Like other algorithm-based classes in Java Security, the
  29.  * Signature class has two major components:
  30.  *
  31.  * <dl>
  32.  *
  33.  * <dt><b>Digital Signature API</b> (Application Program Interface)
  34.  *
  35.  * <dd>This is the interface of methods called by applications needing
  36.  * digital signature services. The API consists of all public methods.
  37.  *
  38.  * <dt><b>Digital Signature SPI</b> (Service Provider Interface)
  39.  *
  40.  * <dd>This is the interface implemented by providers that supply
  41.  * specific algorithms. It consists of all methods whose names are
  42.  * prefixed by <code>engine</code>. Each such method is called by a
  43.  * correspondingly-named public API method. For example, the
  44.  * <code>engineSign</code> method is called by the
  45.  * <code>sign</code> method.  The SPI methods are abstract;
  46.  * providers must supply a concrete implementation.
  47.  *
  48.  * </dl>
  49.  *
  50.  * <p>Also like other algorithm-based classes in Java Security, Signature 
  51.  * provides implementation-independent algorithms, whereby a caller 
  52.  * (application code) requests a particular signature algorithm
  53.  * and is handed back a properly initialized Signature object. It is
  54.  * also possible, if desired, to request a particular algorithm from a
  55.  * particular provider. See the <code>getInstance </code> methods.
  56.  *
  57.  * <p>Thus, there are two ways to request a Signature algorithm object: by
  58.  * specifying either just an algorithm name, or both an algorithm name
  59.  * and a package provider. <ul>
  60.  *
  61.  * <li>If just an algorithm name is specified, the system will
  62.  * determine if there is an implementation of the algorithm requested
  63.  * available in the environment, and if there is more than one, if
  64.  * there is a preferred one.
  65.  * 
  66.  * <li>If both an algorithm name and a package provider are specified,
  67.  * the system will determine if there is an implementation of the
  68.  * algorithm in the package requested, and throw an exception if there
  69.  * is not.
  70.  *
  71.  * </ul>
  72.  
  73.  * <p>A Signature object can be used to generate and verify digital
  74.  * signatures.
  75.  *
  76.  * <p>There are three phases to the use of a Signature object for
  77.  * either signing data or verifying a signature:<ol>
  78.  *
  79.  * <li>Initialization, with either 
  80.  *
  81.  *     <ul>
  82.  *
  83.  *     <li>a public key, which initializes the signature for
  84.  *     verification (see <a href = "#initVerify">initVerify</a>), or
  85.  *
  86.  *     <li>a private key, which initializes the signature for
  87.  *     signing (see <a href = "#initSign">initSign</a>).
  88.  *
  89.  *     </ul><p>
  90.  *
  91.  * <li>Updating<p>
  92.  *
  93.  * <p>Depending on the type of initialization, this will update the
  94.  * bytes to be signed or verified. See the <a href =
  95.  * "#update(byte)">update</a> methods.<p>
  96.  *
  97.  * <li>Signing or Verifying 
  98.  *
  99.  * <p>a signature on all updated bytes. See <a
  100.  * href = "#sign">sign</a> and <a href = "#verify">verify</a>.
  101.  *
  102.  * </ol>
  103.  *
  104.  * @version 1.44 97/02/03
  105.  * @author Benjamin Renaud 
  106.  */
  107. public abstract class Signature {
  108.  
  109.     /*  Are we in debugging mode? */
  110.     private static boolean debug = false;
  111.  
  112.     /* The algorithm for this signature object. */
  113.     private String algorithm;
  114.  
  115.     /** 
  116.      * Possible <a href = "#state ">state </a> value, signifying that       
  117.      * this signature object has not yet been initialized.
  118.      */      
  119.     protected final static int UNINITIALIZED = 0;       
  120.        
  121.     /** 
  122.      * Possible <a href = "#state ">state </a> value, signifying that       
  123.      * this signature object has been initialized for signing.
  124.      */      
  125.     protected final static int SIGN = 2;
  126.        
  127.     /** 
  128.      * Possible <a href = "#state ">state </a> value, signifying that       
  129.      * this signature object has been initialized for verification.
  130.      */      
  131.     protected final static int VERIFY = 3;
  132.  
  133.     /** 
  134.      * Current state of this signature object.
  135.      */      
  136.     protected int state = UNINITIALIZED;
  137.  
  138.     /**
  139.      * Creates a Signature object for the specified algorithm.
  140.      *
  141.      * @param algorithm the standard string name of the algorithm. 
  142.      * See Appendix A in the <a href=
  143.      * "../guide/security/CryptoSpec.html#AppA">
  144.      * Java Cryptography Architecture API Specification & Reference </a> 
  145.      * for information about standard algorithm names.
  146.      */
  147.     protected Signature(String algorithm) {
  148.     this.algorithm = algorithm;
  149.     }
  150.  
  151.     /**
  152.      * Generates a Signature object that implements the specified 
  153.      * algorithm. If the default provider package contains a Signature
  154.      * subclass implementing the algorithm, an instance of that subclass
  155.      * is returned. If the algorithm is not available in the default 
  156.      * package, other packages are searched.
  157.      *
  158.      * @param algorithm the standard name of the algorithm requested. 
  159.      * See Appendix A in the <a href=
  160.      * "../guide/security/CryptoSpec.html#AppA">
  161.      * Java Cryptography Architecture API Specification & Reference </a> 
  162.      * for information about standard algorithm names.
  163.      *
  164.      * @return the new Signature object.
  165.      *
  166.      * @exception NoSuchAlgorithmException if the algorithm is
  167.      * not available in the environment.
  168.      */
  169.     public static Signature getInstance(String algorithm) 
  170.     throws NoSuchAlgorithmException {
  171.     try {
  172.         return (Signature)Security.getImpl(algorithm, "Signature", null);
  173.     } catch(NoSuchProviderException e) {
  174.         throw new InternalError("please send a bug report via " +
  175.                     System.getProperty("java.vendor.url.bug"));
  176.     }
  177.     }
  178.  
  179.     /** 
  180.      * Generates a Signature object implementing the specified
  181.      * algorithm, as supplied from the specified provider, if such an 
  182.      * algorithm is available from the provider.
  183.      *
  184.      * @param algorithm the name of the algorithm requested.
  185.      * See Appendix A in the <a href=
  186.      * "../guide/security/CryptoSpec.html#AppA">
  187.      * Java Cryptography Architecture API Specification & Reference </a> 
  188.      * for information about standard algorithm names.
  189.      *
  190.      * @param provider the name of the provider.
  191.      *
  192.      * @return the new Signature object.
  193.      *
  194.      * @exception NoSuchAlgorithmException if the algorithm is
  195.      * not available in the package supplied by the requested
  196.      * provider.
  197.      *
  198.      * @exception NoSuchProviderException if the provider is not
  199.      * available in the environment. 
  200.      * 
  201.      * @see Provider 
  202.      */
  203.     public static Signature getInstance(String algorithm, String provider) 
  204.     throws NoSuchAlgorithmException, NoSuchProviderException {
  205.  
  206.     return (Signature)Security.getImpl(algorithm, "Signature", provider);
  207.     }
  208.  
  209.     /**
  210.      * Initializes this object for verification. If this method is called
  211.      * again with a different argument, it negates the effect
  212.      * of this call.
  213.      *
  214.      * @param publicKey the public key of the identity whose signature is
  215.      * going to be verified.
  216.      *
  217.      * @exception InvalidKeyException if the key is invalid.
  218.      */
  219.     public final void initVerify(PublicKey publicKey) 
  220.     throws InvalidKeyException {
  221.     engineInitVerify(publicKey);
  222.     state = VERIFY;
  223.     }
  224.  
  225.     /**
  226.      * Initialize this object for signing. If this method is called
  227.      * again with a different argument, it negates the effect
  228.      * of this call.
  229.      *
  230.      * @param privateKey the private key of the identity whose signature
  231.      * is going to be generated.
  232.      * 
  233.      * @exception InvalidKeyException if the key is invalid.  
  234.      */
  235.     public final void initSign(PrivateKey privateKey) 
  236.     throws InvalidKeyException {
  237.     engineInitSign(privateKey);
  238.     state = SIGN;
  239.     }
  240.  
  241.     /**
  242.      * Returns the signature bytes of all the data updated.  The 
  243.      * signature returned is X.509-encoded. 
  244.      * 
  245.      * <p>A call to this method resets this signature object to the state 
  246.      * it was in when previously initialized for signing via a
  247.      * call to <code>initSign(PrivateKey)</code>. That is, the object is 
  248.      * reset and available to generate another signature from the same 
  249.      * signer, if desired, via new calls to <code>update</code> and 
  250.      * <code>sign</code>.     
  251.      *
  252.      * @return the signature bytes of the signing operation's result.
  253.      *
  254.      * @exception SignatureException if this signature object is not
  255.      * initialized properly.
  256.      */
  257.     public final byte[] sign() throws SignatureException {
  258.     if (state == SIGN) {
  259.         return engineSign();
  260.     }
  261.     throw new SignatureException("object not initialized for " +
  262.                      "signing.");
  263.     }
  264.  
  265.     /**
  266.      * Verifies the passed-in signature. The signature bytes are expected 
  267.      * to be X.509-encoded. 
  268.      * 
  269.      * <p>A call to this method resets this signature object to the state 
  270.      * it was in when previously initialized for verification via a
  271.      * call to <code>initVerify(PublicKey)</code>. That is, the object is 
  272.      * reset and available to verify another signature from the identity
  273.      * whose public key was specified in the call to <code>initVerify</code>.
  274.      *      
  275.      * @param signature the signature bytes to be verified.
  276.      *
  277.      * @return true if the signature was verified, false if not. 
  278.      *
  279.      * @exception SignatureException if this signature object is not 
  280.      * initialized properly, or the passed-in signature is improperly 
  281.      * encoded or of the wrong type, etc.  
  282.      */
  283.     public final boolean verify(byte[] signature) 
  284.         throws SignatureException {
  285.     if (state == VERIFY) {
  286.         return engineVerify(signature);
  287.     }
  288.     throw new SignatureException("object not initialized for " +
  289.                      "verification.");
  290.     }
  291.  
  292.     /**
  293.      * Updates the data to be signed or verified by a byte.
  294.      *
  295.      * @param b the byte to use for the update.
  296.      * 
  297.      * @exception SignatureException if this signature object is not 
  298.      * initialized properly.     
  299.      */
  300.     public final void update(byte b) throws SignatureException {
  301.     if (state == VERIFY || state == SIGN) {
  302.         engineUpdate(b);
  303.     } else {
  304.         throw new SignatureException("object not initialized for signature " +
  305.                      "or verification.");
  306.     }
  307.     }
  308.  
  309.     /**
  310.      * Updates the data to be signed or verified, using the specified
  311.      * array of bytes.
  312.      *
  313.      * @param data the byte array to use for the update.       
  314.      * 
  315.      * @exception SignatureException if this signature object is not 
  316.      * initialized properly.          
  317.      */
  318.     public final void update(byte[] data) throws SignatureException {
  319.     update(data, 0, data.length);
  320.     }
  321.  
  322.     /**
  323.      * Updates the data to be signed or verified, using the specified
  324.      * array of bytes, starting at the specified offset.  
  325.      *
  326.      * @param data the array of bytes.  
  327.      * @param off the offset to start from in the array of bytes.  
  328.      * @param len the number of bytes to use, starting at offset.
  329.      *  
  330.      * @exception SignatureException if this signature object is not 
  331.      * initialized properly.          
  332.      */
  333.     public final void update(byte[] data, int off, int len) 
  334.     throws SignatureException {
  335.     if (state == SIGN || state == VERIFY) {
  336.         engineUpdate(data, off, len);
  337.     } else {
  338.         throw new SignatureException("object not initialized for signature " +
  339.                      "or verification.");
  340.     }
  341.     }
  342.  
  343.     /** 
  344.      * Returns the name of the algorithm for this signature object.
  345.      * 
  346.      * @return the name of the algorithm for this signature object.
  347.      */
  348.     public final String getAlgorithm() {
  349.     return algorithm;
  350.     }
  351.  
  352.     /**
  353.      * Returns a string representation of this signature object,       
  354.      * providing information that includes the state of the object       
  355.      * and the name of the algorithm used.       
  356.      * 
  357.      * @return a string representation of this signature object.
  358.      */
  359.     public String toString() {
  360.     String initState = "";
  361.     switch (state) {
  362.     case UNINITIALIZED:
  363.         initState = "<not initialized>";
  364.         break;
  365.       case VERIFY:
  366.         initState = "<initialized for verifying>";
  367.         break;          
  368.       case SIGN:
  369.         initState = "<initialized for signing>";
  370.         break;          
  371.     }
  372.     return "Signature object: " + getAlgorithm() + initState;
  373.     }
  374.  
  375.     /**
  376.      * Sets the specified algorithm parameter to the specified value.
  377.      * This method supplies a general-purpose mechanism through
  378.      * which it is possible to set the various parameters of this object. 
  379.      * A parameter may be any settable parameter for the algorithm, such as 
  380.      * a parameter size, or a source of random bits for signature generation 
  381.      * (if appropriate), or an indication of whether or not to perform
  382.      * a specific but optional computation. A uniform algorithm-specific 
  383.      * naming scheme for each parameter is desirable but left unspecified 
  384.      * at this time.
  385.      *
  386.      * @param param the string identifier of the parameter.
  387.      * @param value the parameter value.
  388.      *
  389.      * @exception InvalidParameterException if <code>param</code> is an
  390.      * invalid parameter for this signature algorithm engine,
  391.      * the parameter is already set
  392.      * and cannot be set again, a security exception occurs, and so on.
  393.      */
  394.     public final void setParameter(String param, Object value) 
  395.     throws InvalidParameterException {
  396.     engineSetParameter(param, value);
  397.     }
  398.  
  399.     /**
  400.      * Gets the value of the specified algorithm parameter. This method 
  401.      * supplies a general-purpose mechanism through which it is possible to 
  402.      * get the various parameters of this object. A parameter may be any 
  403.      * settable parameter for the algorithm, such as a parameter size, or 
  404.      * a source of random bits for signature generation (if appropriate), 
  405.      * or an indication of whether or not to perform a specific but optional 
  406.      * computation. A uniform algorithm-specific naming scheme for each 
  407.      * parameter is desirable but left unspecified at this time.
  408.      *
  409.      * @param param the string name of the parameter.
  410.      *
  411.      * @return the object that represents the parameter value, or null if
  412.      * there is none.
  413.      *
  414.      * @exception InvalidParameterException if <code>param</code> is an invalid
  415.      * parameter for this engine, or another exception occurs while
  416.      * trying to get this parameter.
  417.      */
  418.     public final Object getParameter(String param) 
  419.     throws InvalidParameterException {
  420.         return engineGetParameter(param);
  421.     }
  422.  
  423.     /**
  424.      * <b>SPI</b>: Initializes this signature object with the specified
  425.      * public key for verification operations.
  426.      *
  427.      * @param publicKey the public key of the identity whose signature is
  428.      * going to be verified.
  429.      * 
  430.      * @exception InvalidKeyException if the key is improperly
  431.      * encoded, parameters are missing, and so on.  
  432.      */
  433.     protected abstract void engineInitVerify(PublicKey publicKey)
  434.     throws InvalidKeyException;
  435.  
  436.     /**
  437.      * <b>SPI</b>: Initializes this signature object with the specified
  438.      * private key for signing operations.
  439.      *
  440.      * @param privateKey the private key of the identity whose signature
  441.      * will be generated.
  442.      *
  443.      * @exception InvalidKeyException if the key is improperly
  444.      * encoded, parameters are missing, and so on. 
  445.      */
  446.     protected abstract void engineInitSign(PrivateKey privateKey)
  447.     throws InvalidKeyException;
  448.  
  449.    /**
  450.      * <b>SPI</b>: Updates the data to be signed or verified
  451.      * using the specified byte.
  452.      *
  453.      * @param b the byte to use for the update.
  454.      *
  455.      * @exception SignatureException if the engine is not initialized
  456.      * properly.
  457.      */
  458.     protected abstract void engineUpdate(byte b) throws SignatureException;
  459.  
  460.     /**
  461.      * <b>SPI</b>: Updates the data to be signed or verified, using the 
  462.      * specified array of bytes, starting at the specified offset.
  463.      *
  464.      * @param data the array of bytes.  
  465.      * @param off the offset to start from in the array of bytes.  
  466.      * @param len the number of bytes to use, starting at offset.
  467.      *
  468.      * @exception SignatureException if the engine is not initialized 
  469.      * properly.
  470.      */
  471.     protected abstract void engineUpdate(byte[] b, int off, int len) 
  472.         throws SignatureException;
  473.  
  474.     /** 
  475.      * <b>SPI</b>: Returns the signature bytes of all the data
  476.      * updated so far. The signature returned is X.509-encoded.    
  477.      * For more information about the X.509 encoding, see    
  478.      * <a href = "../guide/security/cert2.html">X.509 certificates</a>.   
  479.      *
  480.      * @return the signature bytes of the signing operation's result.
  481.      *
  482.      * @exception SignatureException if the engine is not
  483.      * initialized properly.  
  484.      */
  485.     protected abstract byte[] engineSign() throws SignatureException;
  486.  
  487.     /** 
  488.      * <b>SPI</b>: Verifies the passed-in signature. The signature bytes 
  489.      * are expected to be X.509-encoded. For more information about the 
  490.      * X.509 encoding, see <a href = "../guide/security/cert2.html">X.509 
  491.      * certificates</a>.   
  492.      * 
  493.      * @param sigBytes the signature bytes to be verified.
  494.      *
  495.      * @return true if the signature was verified, false if not. 
  496.      *
  497.      * @exception SignatureException if the engine is not initialized 
  498.      * properly, or the passed-in signature is improperly encoded or 
  499.      * of the wrong type, etc.  
  500.      */
  501.     protected abstract boolean engineVerify(byte[] sigBytes) 
  502.     throws SignatureException;
  503.  
  504.     /**
  505.      * <b>SPI</b>: Sets the specified algorithm parameter to the specified
  506.      * value. This method supplies a general-purpose mechanism through
  507.      * which it is possible to set the various parameters of this object. 
  508.      * A parameter may be any settable parameter for the algorithm, such as 
  509.      * a parameter size, or a source of random bits for signature generation 
  510.      * (if appropriate), or an indication of whether or not to perform
  511.      * a specific but optional computation. A uniform algorithm-specific 
  512.      * naming scheme for each parameter is desirable but left unspecified 
  513.      * at this time.
  514.      *
  515.      * @param param the string identifier of the parameter.
  516.      *
  517.      * @param value the parameter value.
  518.      *
  519.      * @exception InvalidParameterException if <code>param</code> is an
  520.      * invalid parameter for this signature algorithm engine,
  521.      * the parameter is already set
  522.      * and cannot be set again, a security exception occurs, and so on. 
  523.      */
  524.     protected abstract void engineSetParameter(String param, Object value) 
  525.     throws InvalidParameterException;
  526.  
  527.     /**
  528.      * <b>SPI</b>: Gets the value of the specified algorithm parameter. 
  529.      * This method supplies a general-purpose mechanism through which it 
  530.      * is possible to get the various parameters of this object. A parameter
  531.      * may be any settable parameter for the algorithm, such as a parameter 
  532.      * size, or  a source of random bits for signature generation (if 
  533.      * appropriate), or an indication of whether or not to perform a 
  534.      * specific but optional computation. A uniform algorithm-specific 
  535.      * naming scheme for each parameter is desirable but left unspecified 
  536.      * at this time.
  537.      *
  538.      * @param param the string name of the parameter.
  539.      *
  540.      * @return the object that represents the parameter value, or null if
  541.      * there is none.
  542.      *
  543.      * @exception InvalidParameterException if <code>param</code> is an 
  544.      * invalid parameter for this engine, or another exception occurs while
  545.      * trying to get this parameter.
  546.      */
  547.     protected abstract Object engineGetParameter(String param)
  548.     throws InvalidParameterException;
  549.  
  550.     /**
  551.      * Returns a clone if the implementation is cloneable.
  552.      * 
  553.      * @return a clone if the implementation is cloneable.
  554.      *
  555.      * @exception CloneNotSupportedException if this is called
  556.      * on an implementation that does not support <code>Cloneable</code>.
  557.      */
  558.     public Object clone() throws CloneNotSupportedException {
  559.     if (this instanceof Cloneable) {
  560.         return super.clone();
  561.     } else {
  562.         throw new CloneNotSupportedException();
  563.     }
  564.     }
  565.  
  566.     // private debugging method.
  567.     private static void debug(String statement) {
  568.     if (debug) {
  569.         System.err.println(statement);
  570.     }
  571.     }
  572.  
  573.     // private debugging method.
  574.     private static void debug(Exception e) {
  575.     if (debug) {
  576.         e.printStackTrace();
  577.     }
  578.     }
  579.  
  580. }
  581.     
  582.         
  583.  
  584.  
  585.  
  586.         
  587.         
  588.     
  589.